package com.itlong.cloud.controller.jd.elevator;

import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.PO.AppUserProjectPO;
import com.itlong.cloud.POJO.VO.SDKMessageVO;
import com.itlong.cloud.POJO.VO.app.AppCreateBaiduFaceVO;
import com.itlong.cloud.POJO.VO.jd.JDResultVO;
import com.itlong.cloud.POJO.VO.operate.OperateFaceApplyInfoVO;
import com.itlong.cloud.POJO.VO.sdk.SDKJDAttriButeVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.enumerate.FileCatalogEnum;
import com.itlong.cloud.enumerate.ecode.PropertyErrorCodeEnum;
import com.itlong.cloud.enumerate.jd.JDCodEnum;
import com.itlong.cloud.iottp.IIotBaiduFaceServiceClient;
import com.itlong.cloud.project.operate.IOperateFaceApplyServiceClient;
import com.itlong.cloud.user.property.IPropertyHouseHoldInfoServiceClient;
import com.itlong.cloud.utils.file.ImgageUtil;
import com.itlong.cloud.utils.file.UploadFileUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <desc>
 * 京东接入云设备baseController
 * </desc>
 *
 * @createDate 2020/12/10
 */
public class JDCloudDeviceBaseController {

    private static Logger log = LoggerFactory.getLogger(JDCloudDeviceBaseController.class);

    @Value("${" + PlatformConstants.JD_APPID + "}")
    public String appid;
    @Value("${" + PlatformConstants.JD_SECRET + "}")
    public String secret;
    @Value("${" + PlatformConstants.JD_DOMAIN + "}")
    public String jdUrl;
    //    @Value("${" + PlatformConstants.JD_APPID + "}")
//    private String appid;
//    @Value("${" + PlatformConstants.JD_SECRET + "}")
//    private String appsecret;
    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;
    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;
    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;
    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;
    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;

    @Autowired
    protected IOperateFaceApplyServiceClient iOperateFaceApplyServiceClient;
    @Autowired
    protected IIotBaiduFaceServiceClient iIotBaiduFaceServiceClient;
    @Autowired
    protected IPropertyHouseHoldInfoServiceClient iPropertyHouseHoldInfoServiceClient;
    /**
     * 设置电梯工作模式
     */
    protected final String SET_MODEL = "setModel";
    /**
     * 开放楼层
     */
    protected final String OPEN_FLOOR = "openFloor";
    /**
     * 预约乘梯
     */
    protected final String RESERVE = "reserve";
    /**
     * 电梯状态上报控制
     */
    protected final String DOOR_CTRL = "doorCtrl";
    /**
     * 电梯开关状态上报
     */
    protected final String DEVICE_REPORT_CTRL = "deviceReportCtrl";
    /**
     * 人脸注册-业主
     */
    protected final String ADD_USER = "addUser";
    /**
     * 信息修改-业主
     */
    protected final String UPDATE_USER = "updateUser";
    /**
     * 信息修改-删除
     */
    protected final String REMOVE_USER = "removeUser";
    /**
     * 人脸注册-访客
     */
    protected final String ADD_VISITOR = "addVisitor";
    /**
     * 权限变更-乘梯
     */
    protected final String ELEVATOR_AUTH_ALTER = "elevatorAuthAlter";
    /**
     * 权限查询
     */
    protected final String GET_ALLELEVATOR_INFO = "getAllElevatorInfo";

    /**
     * <desc>
     * 通过反射封装京东需要获取的设备属性
     * </desc>
     *
     * @param properties
     * @param vo
     * @return
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @author Jiaqi.X
     * @createDate 2020/08/11
     */
    protected Map<String, Object> getProperties(List<String> properties, SDKJDAttriButeVO vo) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //List<String> result = properties;
        Map<String, Object> result = new HashMap<>(16);
        Field[] fields = vo.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (properties.stream().filter(r -> r.equals(field.getName())).findFirst().isPresent()) {
                //获取get属性方法名
                String name = field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
                Method m = vo.getClass().getMethod("get" + name);
                Object value = m.invoke(vo);
                if (null != value) {
                    result.put(field.getName(), value);
                } else {
                    result.put(field.getName(), "");
                }

            }
        }
        return result;
    }


    /**
     * <desc>
     * 保存人脸
     * <desc/>
     *
     * @param imageStr
     * @param jdProjectId
     * @param isVisitor
     * @param userId
     * @param passId
     * @param isUpdateUserFace
     *
     * @return JDResultVO
     * @author pengwei
     * @createDate 2020-12-09
     */
    protected   JDResultVO   saveFace(String imageStr,String jdProjectId,boolean isVisitor,String userId,String passId,boolean  isUpdateUserFace)throws  Exception{
            //判断项目是否开启人脸识别,并查询是否有百度库key
            OperateFaceApplyInfoVO operateFaceApplyInfoVO = iOperateFaceApplyServiceClient.getFaceByProjectId(jdProjectId);
            if (operateFaceApplyInfoVO == null) {
                return   new JDResultVO(JDCodEnum.PROJECT_FACE_APPID_INEXISTENCE.getCode());
            }
            AppCreateBaiduFaceVO appCreateBaiduFaceVO = new AppCreateBaiduFaceVO();
            appCreateBaiduFaceVO.setAPP_ID(operateFaceApplyInfoVO.getAppId());
            appCreateBaiduFaceVO.setAPI_KEY(operateFaceApplyInfoVO.getApiKey());
            appCreateBaiduFaceVO.setSECRET_KEY(operateFaceApplyInfoVO.getSecretKey());
            appCreateBaiduFaceVO.setFaceScore(operateFaceApplyInfoVO.getFaceScore() == 0F ? 80F : operateFaceApplyInfoVO.getFaceScore());
            appCreateBaiduFaceVO.setImageUrl(imageStr);
//            //判断图片分辨率
//            BufferedImage bi = ImageIO.read(new ByteArrayInputStream(new BASE64Decoder().decodeBuffer(imageStr)));
//            if(bi==null){
//                JDResultVO   jv  =  new JDResultVO(JDCodEnum.PARAMETER_INVALID.getCode());
//                jv.setMessage(new StringBuilder(jv.getMessage()).append("[").append(imageStr).append("]").toString());
//                return jv;
//            }
//            int width = bi.getWidth();
//            int height = bi.getHeight();
//            if (width < 640 || height < 480 || width > 2560 || height > 2560) {
//                return   new JDResultVO(JDCodEnum.APPUSER_FACE_RESOLUTION_RATIO_ERROR.getCode());
//            }
//            //保存图片
//            String uploadFilePath = uploadImageFile(new BASE64Decoder().decodeBuffer(imageStr), "png", FileCatalogEnum.BAIDU_FACE_CREATE_FILE);
//            appCreateBaiduFaceVO.setImageUrl(uploadFilePath);
            if(!isVisitor){
                //业主
                appCreateBaiduFaceVO.setUid(userId);
            }
            SDKMessageVO messageVO = this.checkFace(appCreateBaiduFaceVO);
            if (messageVO != null) {
                return new JDResultVO(messageVO.getMsgCode(),messageVO.getMsg());
            }
            if(isVisitor){
                //访客
                String repeatResult = iIotBaiduFaceServiceClient.identifyUser(appCreateBaiduFaceVO);//拿到现有的id
                if (StringUtils.isNotEmpty(repeatResult)) {
                    if ("error".equals(repeatResult)||"busy".equals(repeatResult)) {
                        return new JDResultVO(JDCodEnum.USER_FACE_IDENTIFY_ERROR.getCode());
                    }
                }
                String vFaceId=null;
                //判断认证图片是否重复
                if (repeatResult == null) {//人脸库中无此人脸ID使用V_ + pass_id
                    appCreateBaiduFaceVO.setUid("V_" + passId);
                    //创建百度人脸信息
                    boolean result = iIotBaiduFaceServiceClient.doCreateBaiduFaceForVisitor(appCreateBaiduFaceVO);
                    if (!result) {
                        return new JDResultVO(JDCodEnum.SUCCESS.getCode());
                    }
                    vFaceId = appCreateBaiduFaceVO.getUid();
                } else {//人脸库中有此人脸
                    //有此人脸时证明这个人在此项目中注册过人脸业主使用的是这个人的user_id,访客使用的是V_ + pass_id   不进行重复注册
                    if (repeatResult.substring(0, 2).equals("V_")) {//访客人脸则进行覆盖
                        appCreateBaiduFaceVO.setUid(repeatResult);
                        //创建百度人脸信息
                        boolean result = iIotBaiduFaceServiceClient.doCreateBaiduFaceForVisitor(appCreateBaiduFaceVO);
                        if (!result) {
                            return new JDResultVO(JDCodEnum.SUCCESS.getCode());
                        }
                    }
                    vFaceId = repeatResult;
                }
                JSONObject    updateJson  = new JSONObject();
                updateJson.put("passId",passId);
                updateJson.put("vFaceId",vFaceId);
                updateJson.put("uploadFilePath",imageStr);
                iPropertyHouseHoldInfoServiceClient.jdVisitorUpdate(updateJson);
            }else{
                //保存业主数据
                AppUserProjectPO appUserProjectPO = new AppUserProjectPO();
                appUserProjectPO.setUserId(userId);
                appUserProjectPO.setProjectId(jdProjectId);
                appUserProjectPO.setFacePicUrl(imageStr);
                appUserProjectPO.setUpdateTime(new Date());
                if(!isUpdateUserFace){
                    //业主人脸注册，非人脸修改，创建时间要写入数据库
                    appUserProjectPO.setFaceCreateTime(new Date());
                }
                appUserProjectPO.setIsFace(1);//认证中
                iPropertyHouseHoldInfoServiceClient.updatePreUserBaiduFaceInfo(appUserProjectPO);
            }
            return   new JDResultVO(JDCodEnum.SUCCESS.getCode());
    }


//    /**
//     * <desc>
//     *
//     * </desc>
//     *
//     * @param
//     * @return
//     * @Author Zhu.yj
//     * @createDate  2021/1/20
//     */
//    @PostMapping("uploadImage")
//    public Object uploadImage(){
//        try{
//            String str = JDAPI.ImageToBase64ByOnline("https://tmp.img.jia-r.com/baiduFaceCreateFile/21/01/20/210120134334534JIPZ.png");
////记得把头给截取掉
//            String uploadFilePath = uploadImageFile(new BASE64Decoder().decodeBuffer(str), "png", FileCatalogEnum.BAIDU_FACE_CREATE_FILE);
//            return uploadFilePath;
//        }catch (Exception e){
//            throw new DataAccessException(e);
//        }
//    }

    /**
     * <desc>
     * 上传图片文件
     * <desc/>
     *
     * @param bytes     图片二进制
     * @param imageType 图片类型
     * @return
     * @author Qiang.S
     * @createDate 2018-05-18
     */
    protected String uploadImageFile(byte[] bytes, String imageType, FileCatalogEnum fileCatalog) {
        byte[] newbytes = ImgageUtil.stringToImage(bytes, imageType);
        ByteArrayInputStream byteArrayInputStream = null;
        if (newbytes != null) {
            byteArrayInputStream = new ByteArrayInputStream(newbytes);
        } else {
            byteArrayInputStream = new ByteArrayInputStream(bytes);
        }
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                byteArrayInputStream,
                imageType,
                FILE_ACCESS_URL,
                fileCatalog.getType()
        );

        try {
            //log.info("正在上传图片");
            Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
            //log.info("图片上传完毕");
            String returnCode = resultMap.get("returnCode").toString();
            if ("true".equals(returnCode)) {
                String fileUrl = resultMap.get("accessPath").toString();
                return fileUrl;
            } else {
                log.info(String.format("图片上传失败，returnCode: %s", returnCode));
                return null;
            }
        } catch (IOException e) {
            log.info("UploadFileUtil.uploadFile失败", e);
            return null;
        }
    }



    /**
     * <desc>
     * 人脸判断
     * <desc/>
     *
     * @return Object   标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/11/05
     */
    private SDKMessageVO checkFace(AppCreateBaiduFaceVO appCreateBaiduFaceVO) {
        String checkResult = iIotBaiduFaceServiceClient.faceVerify(appCreateBaiduFaceVO);
        if (checkResult != null && !"".equals(checkResult)) {
            if ("error".equals(checkResult)) {//调用接口异常
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACEVERFY_ERROR.getErrorCode(),
                        appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("busy".equals(checkResult)) {//调用接口忙
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_BAIDU_BUSY.getErrorCode(),
                        appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("others".equals(checkResult)) {//图片不合格,非真人图片
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_BAIDU_PICTURE_ERROR.getErrorCode(),
                        appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("result_num".equals(checkResult)) {//人脸数异常
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_RESULTNUM_NOT_1.getErrorCode(),
                        appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("size".equals(checkResult)) {//人脸太小
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_SIZE_TOO_SMALL.getErrorCode(),
                        appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            //2020年8月5号 按照需求说明取消活体检测
           /* if ("faceliveness".equals(checkResult)) {//活体值异常
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_FACELIVENESS_TOO_LOW.getErrorCode(),appCreateBaiduFaceVO.getRequestId(),appCreateBaiduFaceVO.getResponseTimestamp(),"");
            }*/
            if ("left_eye".equals(checkResult) || "right_eye".equals(checkResult) || "nose".equals(checkResult)
                    || "mouth".equals(checkResult) || "left_cheek".equals(checkResult) || "right_cheek".equals(checkResult)
                    || "chin".equals(checkResult)) {//图片遮挡
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_OCCLUSION.getErrorCode(),
                        appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("blur".equals(checkResult)) {//模糊
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_BLUR_TOO_LOW.getErrorCode(),
                        appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("illumination_min".equals(checkResult)) {//光照过暗
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_ILLUMINATION_TOO_LOW.getErrorCode(),
                        appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("illumination_max".equals(checkResult)) {//光照过亮
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_ILLUMINATION_TOO_HIGH.getErrorCode(),
                        appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("pitch".equals(checkResult) || "roll".equals(checkResult) || "yaw".equals(checkResult)) {//角度
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_ANGLE_NOT_STRAIGHT.getErrorCode(),
                        appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("completeness".equals(checkResult)) {//人脸完整度
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_COMPLETENESS_IMPERFECT.getErrorCode(),
                        appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
        }
        return  null;
    }
}
